package com.xpec.canaan.util;

import java.util.Vector;

import org.tmatesoft.svn.core.SVNCancelException;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.wc.ISVNEventHandler;
import org.tmatesoft.svn.core.wc.SVNEvent;
import org.tmatesoft.svn.core.wc.SVNEventAction;
import org.tmatesoft.svn.core.wc.SVNStatusType;

public class UpdateEventLogHandler implements ISVNEventHandler {

	/**
	 * Default Constructor
	 * 
	 */
	public UpdateEventLogHandler()
	{
		m_dumpedMessage = new Vector<EventMessageRecorder>();
	}
	
	@Override
	public void handleEvent(SVNEvent event, double progress) throws SVNException {
		/*
         * Gets the current action. An action is represented by SVNEventAction.
         * In case of an update an  action  can  be  determined  via  comparing 
         * SVNEvent.getAction() and SVNEventAction.UPDATE_-like constants. 
         */
		
		EventMessageRecorder nRecord = new EventMessageRecorder(m_parentEvent);
		m_dumpedMessage.add(nRecord);
		
        SVNEventAction action = event.getAction();
        
        if (action == SVNEventAction.UPDATE_ADD) {
            /*
             * the item was added
             */
        
            nRecord.setSubEvent("[REPOSITORY_ADD]");
        } else if (action == SVNEventAction.UPDATE_DELETE) {
            /*
             * the item was deleted
             */
        
            nRecord.setSubEvent("[REPOSITORY_DELETE]");
        } else if (action == SVNEventAction.UPDATE_UPDATE) {
            /*
             * Find out in details what  state the item is (after  having  been 
             * updated).
             * 
             * Gets  the  status  of  file/directory  item   contents.  It   is 
             * SVNStatusType  who contains information on the state of an item.
             */
            SVNStatusType contentsStatus = event.getContentsStatus();
            if (contentsStatus == SVNStatusType.CHANGED) {
                /*
                 * the  item  was  modified in the repository (got  the changes 
                 * from the repository
                 */
        
                nRecord.setSubEvent("[REPOSITORY_CHANGED]");
            }else if (contentsStatus == SVNStatusType.CONFLICTED) {
                /*
                 * The file item is in  a  state  of Conflict. That is, changes
                 * received from the repository during an update, overlap  with 
                 * local changes the user has in his working copy.
                 */
            
                nRecord.setSubEvent("[REPOSITORY_CONFILCTED]");
            } else if (contentsStatus == SVNStatusType.MERGED) {
                /*
                 * The file item was merGed (those  changes that came from  the 
                 * repository  did  not  overlap local changes and were  merged 
                 * into the file).
                 */
            
                nRecord.setSubEvent("[REPOSITORY_MERGED]");
            }
        } else if (action == SVNEventAction.UPDATE_EXTERNAL) {
            /*for externals definitions*/
        	nRecord.setSubEvent("[REPOSITORY_EXTERNAL]");
        	nRecord.addMessage("Fetching external item into '" + event.getFile().getAbsolutePath() + "'");
        	nRecord.addMessage("External at revision " + event.getRevision());
            return;
        } else if (action == SVNEventAction.UPDATE_COMPLETED) {
            /*
             * Updating the working copy is completed. Prints out the revision.
             */
        	nRecord.setSubEvent("[UPDATE_COMPLETE]");
        	nRecord.addMessage("At revision" + event.getRevision());
            return;
        } else if (action == SVNEventAction.ADD){
        	nRecord.setSubEvent("[UPDATE_SCHEDULED_ADD]");
        	nRecord.addMessage( event.getFile().toString());
            return;
        } else if (action == SVNEventAction.DELETE){
        	nRecord.setSubEvent("[UPDATE_SCHEDULED_DELETE]");
        	nRecord.addMessage(event.getFile().toString());
            return;
        } else if (action == SVNEventAction.LOCKED){
        	nRecord.setSubEvent("[UPDATE_FILE_LOCKED]");
        	nRecord.addMessage(event.getFile().toString());
            return;
        } else if (action == SVNEventAction.LOCK_FAILED){
        	nRecord.setSubEvent("[UPDATE_FILE_LOCK_FAILED]");
        	nRecord.addMessage(event.getFile().toString());
            return;
        }

        /*
         * Now getting the status of properties of an item. SVNStatusType  also
         * contains information on the properties state.
         */
        SVNStatusType propertiesStatus = event.getPropertiesStatus();
        /*
         * At first consider properties are normal (unchanged).
         */
        
        if (propertiesStatus == SVNStatusType.CHANGED) {
            /*
             * Properties were updated.
             */
        	nRecord.setSubEvent("[UPDATE_CHANGED]");
        } else if (propertiesStatus == SVNStatusType.CONFLICTED) {
            /*
             * Properties are in conflict with the repository.
             */
        	nRecord.setSubEvent("[UPDATE_CONFILCTED]");
        } else if (propertiesStatus == SVNStatusType.MERGED) {
            /*
             * Properties that came from the repository were  merged  with  the
             * local ones.
             */
        	nRecord.setSubEvent("[UPDATE_MERGED]");
        }

        /*
         * Gets the status of the lock.
         */
        SVNStatusType lockType = event.getLockStatus();
        
        if (lockType == SVNStatusType.LOCK_UNLOCKED) {
            /*
             * The lock is broken by someone.
             */
        	nRecord.setSubEvent("[UPDATE_LOCKED]");
        }
        
        if( null == nRecord.getSubEvent() )
        {
        	nRecord.setSubEvent("[UPDATE_NOTHING]");
        }
        
        nRecord.addMessage(event.getFile().toString());
        
        System.out.println(nRecord.toString());
	}
	
	
	@Override
	public void checkCancelled() throws SVNCancelException {
		
	}
	
	public Vector<EventMessageRecorder> getDumpedMessage()
	{
		return m_dumpedMessage;
	}
	
	private static final String m_parentEvent = "[UPDATE]";
	private Vector<EventMessageRecorder> m_dumpedMessage;
}
